"""
认证相关的API端点

处理用户认证相关的请求，包括注册、登录、密码管理等。
"""

from datetime import datetime
from typing import Any

from fastapi import APIRouter, Depends, HTTPException, status, BackgroundTasks
from fastapi.security import OAuth2PasswordRequestForm
from sqlalchemy.ext.asyncio import AsyncSession

from app.db.session import get_db
from app.modules.auth.schemas import (
    UserRegister, UserProfile, Token,
    PasswordResetRequest, PasswordReset, EmailVerify
)
from app.modules.auth.services import auth_service
from app.modules.auth.config import settings

router = APIRouter()


@router.post("/register", response_model=UserProfile, status_code=status.HTTP_201_CREATED)
async def register(
    user_data: UserRegister,
    db: AsyncSession = Depends(get_db),
    background_tasks: BackgroundTasks = None
):
    """
    注册新用户
    
    注册成功后，如果需要邮箱验证，将发送验证邮件。
    """
    # 检查是否允许注册
    if not settings.ALLOW_REGISTRATION:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="当前不允许新用户注册"
        )
    
    # 注册用户
    user, error = await auth_service.register_user(
        db, email=user_data.email, password=user_data.password, full_name=user_data.full_name
    )
    
    if error:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=error
        )
    
    # 如果需要邮箱验证并提供了后台任务，添加发送验证邮件的任务
    if settings.EMAIL_VERIFICATION_REQUIRED and background_tasks:
        # 生成验证令牌
        token = auth_service.generate_email_verification_token(user.email)
        # 添加发送邮件任务
        # background_tasks.add_task(send_verification_email, user.email, token)
    
    return user


@router.post("/login", response_model=Token)
async def login(
    form_data: OAuth2PasswordRequestForm = Depends(),
    db: AsyncSession = Depends(get_db)
):
    """
    用户登录
    
    使用邮箱和密码登录，返回访问令牌。
    """
    # 验证用户
    user = await auth_service.authenticate_user(
        db, email=form_data.username, password=form_data.password
    )
    
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="邮箱或密码不正确",
            headers={"WWW-Authenticate": "Bearer"},
        )
    
    # 创建访问令牌
    access_token, expires_at = auth_service.create_access_token(user.id)
    
    return {
        "access_token": access_token,
        "token_type": "bearer",
        "expires_at": expires_at
    }


@router.post("/password-reset-request", status_code=status.HTTP_202_ACCEPTED)
async def request_password_reset(
    request_data: PasswordResetRequest,
    db: AsyncSession = Depends(get_db),
    background_tasks: BackgroundTasks = None
):
    """
    请求密码重置
    
    发送密码重置邮件（如果用户存在）。
    """
    # 检查用户是否存在
    user = await auth_service.get_user_by_email(db, email=request_data.email)
    
    # 即使用户不存在，也返回成功，以防止邮箱枚举攻击
    if user and background_tasks:
        # 生成重置令牌
        token = auth_service.generate_password_reset_token(user.email)
        # 添加发送邮件任务
        # background_tasks.add_task(send_password_reset_email, user.email, token)
    
    return {"message": "如果该邮箱已注册，将收到密码重置邮件"}


@router.post("/password-reset", status_code=status.HTTP_200_OK)
async def reset_password(
    reset_data: PasswordReset,
    db: AsyncSession = Depends(get_db)
):
    """
    重置密码
    
    使用重置令牌设置新密码。
    """
    success, error = await auth_service.reset_password(
        db, token=reset_data.token, new_password=reset_data.new_password
    )
    
    if not success:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=error or "密码重置失败"
        )
    
    return {"message": "密码已成功重置"}


@router.post("/verify-email", status_code=status.HTTP_200_OK)
async def verify_email(
    verify_data: EmailVerify,
    db: AsyncSession = Depends(get_db)
):
    """
    验证邮箱
    
    使用验证令牌验证用户邮箱。
    """
    success, error = await auth_service.verify_email(db, token=verify_data.token)
    
    if not success:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=error or "邮箱验证失败"
        )
    
    return {"message": "邮箱已成功验证"} 